#include "D3D9_PCH.h"
#include "D3D9Effect.h"
#include "VisibleComponent.h"

CD3DEffect::CD3DEffect( const TString& EffectFileName )
	: m_pEffect( NULL )
{
	_CreateEffectFromFile( EffectFileName );
}

CD3DEffect::CD3DEffect( const BYTE* CompiledEffectBuffer, const int SizeOfBuffer )
{
	D3DXCreateEffect( *g_pDevice, CompiledEffectBuffer, SizeOfBuffer, NULL, NULL, D3DXSHADER_SKIPVALIDATION, 0, &m_pEffect, NULL );
}

CD3DEffect::~CD3DEffect(void)
{
	SAFE_RELEASE( m_pEffect );
}

BOOL CD3DEffect::_CreateEffectFromFile( const TString& EffectFileName ) {
	HRESULT hr;
	LPD3DXBUFFER Error = NULL;

#ifdef _DEBUG
	hr = D3DXCreateEffectFromFile( *g_pDevice, EffectFileName.c_str(), NULL, NULL, D3DXSHADER_DEBUG, 0, &m_pEffect, &Error );
#else
	hr = D3DXCreateEffectFromFile( *g_pDevice, EffectFileName.c_str(), NULL, NULL, 0, 0, &m_pEffect, &Error );
#endif
	
	if ( FAILED(hr) ) {
		TString ErrorMsg;
		if ( Error == NULL ) {
			ErrorMsg = _T("Cannot find shader file ");
		}
		else {
			ErrorMsg = _T("D3DXCreateEffectFromFile() - FAILED at ");

			// Complie Error Messages
			::MessageBoxA(0, (LPCSTR)Error->GetBufferPointer(), 0, 0);
			SAFE_RELEASE(Error);
		}
		ErrorMsg += EffectFileName;
		::MessageBox( 0, ErrorMsg.c_str(), 0, 0 );

		return FALSE;
	}
	
	return TRUE;
}

const UINT CD3DEffect::Activate( LPCSTR techniqueName ) const {
	assert( m_pEffect );

	D3DXHANDLE technique = 0;
	technique = m_pEffect->GetTechniqueByName( techniqueName );
	m_pEffect->SetTechnique( technique );
	
	UINT numPasses = 0;
	m_pEffect->Begin( &numPasses, 0 );

	return numPasses;
}

void CD3DEffect::Deactivate() const {
	assert( m_pEffect );
	m_pEffect->End();
}

void CD3DEffect::BeginPass( const UINT PassIndex ) const {
	assert( m_pEffect );
	m_pEffect->BeginPass( PassIndex );
}

void CD3DEffect::EndPass() const {
	assert( m_pEffect );
	m_pEffect->EndPass();
}

void CD3DEffect::Render( LPCSTR techniqueName, IVisibleComponent* pComponent ) const {
	assert( m_pEffect );

	pComponent->PreRender();

	D3DXHANDLE technique = 0;
	technique = m_pEffect->GetTechniqueByName( techniqueName );
	m_pEffect->SetTechnique( technique );
	
	UINT numPasses = 0;
	m_pEffect->Begin( &numPasses, 0 );

	for ( UINT i=0; i<numPasses; ++i ) {
		m_pEffect->BeginPass( i );
		pComponent->Render();
		m_pEffect->EndPass();
	}

	m_pEffect->End();
	pComponent->PostRender();
}

void CD3DEffect::setMatrix( LPCSTR hParameter, const D3DXMATRIX* Src ) {
	assert( m_pEffect );
	HRESULT hr = 0;
//	hr = m_pEffect->SetMatrix( m_pEffect->GetParameterByName(NULL,hParameter), Src );
	hr = m_pEffect->SetMatrix( hParameter, Src );
	assert(hr == D3D_OK);
}

void CD3DEffect::setFloat( LPCSTR hParameter, FLOAT Src ) {
	assert( m_pEffect );
	HRESULT hr = 0;
//	hr = m_pEffect->SetFloat( m_pEffect->GetParameterByName(NULL,hParameter), Src );
	hr = m_pEffect->SetFloat( hParameter, Src );
	assert(hr == D3D_OK);
}

void CD3DEffect::setTexture( LPCSTR hParameter, IDirect3DTexture9* pTexture ) {
	assert( m_pEffect );
	HRESULT hr = 0;
	hr = m_pEffect->SetTexture( hParameter, pTexture );
	assert( hr == D3D_OK );
}